package de.koller.aframe.gl;

import de.koller.oceanFramework.gl.util.DisplayModeChooser;
import de.koller.oceanFramework.gl.util.TextureUtil;
import de.koller.oceanFramework.thread.IPipe;
import de.koller.oceanFramework.thread.Pipeline;
import java.nio.ByteBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.PixelFormat;

public class ADisplayGL {
	public final int width;
	public final int height;
	private final String title;
	
	private final boolean fullscreen;
	private final boolean vSync;
	
	public static boolean enableClientChoose = false;
	private String ip;
	private boolean asClient;
	
	private final DisplayMode displayMode;
	
	public static ADisplayGL create( String title ) {
		return create( title, -1, -1, -1, -1, false, false );
	}
	
	public static ADisplayGL create( String title, int width, int height, int depth, int freq, boolean filter, boolean full ) {
		final DisplayModeChooser dmc = new DisplayModeChooser();
		if( width != -1 )
			dmc.setWished( width, height, depth, freq, filter, full );
		
		Pipeline pl = new Pipeline( new IPipe() {
			@Override public void updateSubStep() {
				synchronized( dmc ) {
					try {
						while( dmc.getChoosedMode() == null )
							dmc.wait();
					} catch( InterruptedException ex ) { 
						System.err.println( ex ); 
					}
				}
			}
			@Override public String getName() { return "DMC"; }
		} );
	
		pl.stepPipes();
		
		ADisplayGL disp = new ADisplayGL( dmc.getChoosedMode(), title, dmc.isFullscreen(), dmc.isVsync() );
		disp.asClient = dmc.isAsClient();
		disp.ip = dmc.getIP();
		
		return disp;
	}
	
	public static ADisplayGL forceCreate( String title, int width, int height ) {
		return new ADisplayGL( new DisplayMode( width, height ), title, false, false );
	}
	
	private ADisplayGL( DisplayMode mode, String title, boolean fullscreen, boolean vsync ) {
		this.displayMode = mode;
		this.width = mode.getWidth();
		this.height = mode.getHeight();
		this.title = title;
		this.fullscreen = fullscreen;
		this.vSync = vsync;
	}

	public void start() {
		try {
			Display.setIcon( new ByteBuffer[] {
				TextureUtil.load( "data/icons/icon132.png" ).generateByteBuffer(),
				TextureUtil.load( "data/icons/icon116.png" ).generateByteBuffer()
			} );

			Display.setDisplayMode( displayMode );
			Display.setFullscreen( fullscreen );
			if( fullscreen )
				Display.setVSyncEnabled( vSync );
			Display.setTitle( title );

			System.out.println( "Display created: " + displayMode.getWidth() + "x"
					+ displayMode.getHeight() + "x" + displayMode.getBitsPerPixel() +
					" " + displayMode.getFrequency() + "Hz" );
			Display.create( new PixelFormat( 32, 0, 24, 8, 0 ) );
		} catch( Exception e ) {
			e.printStackTrace();
			System.exit(0);
		}
		 
		initGL();
	}
	
	public void stop() {
		try {
			Display.setFullscreen( false );
		} catch( LWJGLException ex ) { System.err.println( ex ); }
		Display.destroy();
	}

	
	public void update() {
		Display.update();
	}
	
	public long getTime() {
		return (Sys.getTime() * 1000) / Sys.getTimerResolution();
	}
 
	private void initGL() {
		GL11.glShadeModel( GL11.GL_SMOOTH );
		
		GL11.glMatrixMode( GL11.GL_MODELVIEW );
		GL11.glLoadIdentity();
	}
	
	
}
